<!DOCTYPE html>
<html>
<head>
<title>Wollaston Prism Setup</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
  }
  canvas {
    border: 1px solid #ccc;
    background-color: #fff;
  }
</style>
</head>
<body>
<canvas id="physicsCanvas" width="800" height="400"></canvas>
<script>
const canvas = document.getElementById('physicsCanvas');
const ctx = canvas.getContext('2d');

function drawArrow(ctx, fromx, fromy, tox, toy, arrowHeadLength = 10) {
    const dx = tox - fromx;
    const dy = toy - fromy;
    const angle = Math.atan2(dy, dx);
    ctx.beginPath();
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.stroke();
    ctx.save();
    ctx.translate(tox, toy);
    ctx.rotate(angle);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, arrowHeadLength / 2);
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, -arrowHeadLength / 2);
    ctx.stroke();
    ctx.restore();
}

function drawDoubleArrow(ctx, x, y, length, angle_deg) {
    const l = length / 2;
    const rad = angle_deg * Math.PI / 180;
    const cos = Math.cos(rad);
    const sin = Math.sin(rad);
    
    const x1 = x - l * cos;
    const y1 = y - l * sin;
    const x2 = x + l * cos;
    const y2 = y + l * sin;

    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    
    const arrowHeadLength = 8;
    // Arrowhead at (x2, y2)
    ctx.save();
    ctx.translate(x2, y2);
    ctx.rotate(rad);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, arrowHeadLength / 2.5);
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, -arrowHeadLength / 2.5);
    ctx.stroke();
    ctx.restore();

    // Arrowhead at (x1, y1)
    ctx.save();
    ctx.translate(x1, y1);
    ctx.rotate(rad + Math.PI);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, arrowHeadLength / 2.5);
    ctx.moveTo(0, 0);
    ctx.lineTo(-arrowHeadLength, -arrowHeadLength / 2.5);
    ctx.stroke();
    ctx.restore();
}

function drawArrowhead(ctx, x, y, angle_rad, size=10) {
    ctx.save();
    ctx.translate(x, y);
    ctx.rotate(angle_rad);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(-size, size / 2.5);
    ctx.moveTo(0, 0);
    ctx.lineTo(-size, -size / 2.5);
    ctx.stroke();
    ctx.restore();
}

// Canvas setup
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.lineWidth = 2;

// 1. Incoming light beam and label I_i
const y_center = 200;
ctx.font = 'italic 22px Times New Roman';
drawArrow(ctx, 50, y_center, 180, y_center);
ctx.fillText('I', 110, 185);
ctx.font = 'italic 16px Times New Roman';
ctx.fillText('i', 122, 190);


// 2. Polarizer P
const p_back_x = 230;
const p_front_x = 250;
const p_y = 200;
const p_rad_y = 65;
const p_rad_x = 12;

ctx.fillStyle = '#E0E0E0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.5;

ctx.beginPath();
ctx.moveTo(p_back_x, p_y - p_rad_y);
ctx.lineTo(p_front_x, p_y - p_rad_y);
ctx.ellipse(p_front_x, p_y, p_rad_x, p_rad_y, 0, -Math.PI/2, Math.PI/2);
ctx.lineTo(p_back_x, p_y + p_rad_y);
ctx.ellipse(p_back_x, p_y, p_rad_x, p_rad_y, 0, Math.PI/2, -Math.PI/2);
ctx.closePath();
ctx.fill();
ctx.stroke();

// Draw rotation arrow on the front face
ctx.lineWidth = 1.5;
const arrow_rx = p_rad_x * 0.8;
const arrow_ry = p_rad_y * 0.7;
const arc_start_angle = Math.PI * 0.4;
const arc_end_angle = Math.PI * 1.9;

ctx.beginPath();
ctx.ellipse(p_front_x, p_y, arrow_ry, arrow_rx, Math.PI/2, arc_start_angle, arc_end_angle, false); // CW
ctx.stroke();

// Arrowhead at the end of the arc
const t = arc_end_angle;
const x_end = p_front_x - arrow_rx * Math.sin(t);
const y_end = p_y + arrow_ry * Math.cos(t);
const tangent_angle = Math.atan2(arrow_ry*Math.sin(t), -arrow_rx*Math.cos(t)) + Math.PI/2;
drawArrowhead(ctx, x_end, y_end, tangent_angle, 10);


// Label P
ctx.font = 'bold 24px Times New Roman';
ctx.fillText('P', p_front_x - 10, 115);

// 3. Ray from Polarizer to Prism
ctx.lineWidth = 2;
drawArrow(ctx, p_front_x + p_rad_x, y_center, 350, y_center);

// 4. Wollaston Prism
const prism_x_start = 350;
const prism_x_end = 470;
const prism_y_top = 140;
const prism_y_bottom = 260;
const prism_center_x = (prism_x_start + prism_x_end) / 2; // 410
const prism_center_y = y_center; // 200

ctx.fillStyle = '#E0E0E0';
ctx.lineWidth = 2.5;
ctx.beginPath();
ctx.rect(prism_x_start, prism_y_top, prism_x_end - prism_x_start, prism_y_bottom - prism_y_top);
ctx.fill();
ctx.stroke();

ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(prism_x_start, prism_y_bottom);
ctx.lineTo(prism_x_end, prism_y_top);
ctx.stroke();

// Dashed line inside
ctx.beginPath();
ctx.setLineDash([5, 3]);
ctx.moveTo(380, 165);
ctx.lineTo(380, 235);
ctx.stroke();
ctx.setLineDash([]); // Reset

// Dot for optic axis
ctx.beginPath();
ctx.arc(400, 175, 3.5, 0, 2 * Math.PI);
ctx.fill();

// Ray path inside prism
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(prism_x_start, y_center);
ctx.lineTo(prism_center_x, prism_center_y);
ctx.stroke();


// 5. Outgoing rays
const ray_end_x = 680;
const angle_factor = 0.35;

// Upper ray (I_o)
const o_ray_end_y = prism_center_y - (ray_end_x - prism_center_x) * angle_factor;
drawArrow(ctx, prism_center_x, prism_center_y, ray_end_x, o_ray_end_y);

// Lower ray (I_e)
const e_ray_end_y = prism_center_y + (ray_end_x - prism_center_x) * angle_factor;
drawArrow(ctx, prism_center_x, prism_center_y, ray_end_x, e_ray_end_y);

// 6. Polarization Markings
// For upper ray (I_o)
const pol_o_x = prism_center_x + 120;
const pol_o_y = prism_center_y - (pol_o_x - prism_center_x) * angle_factor;
ctx.lineWidth = 1.5;
drawDoubleArrow(ctx, pol_o_x, pol_o_y, 35, 45);
drawDoubleArrow(ctx, pol_o_x, pol_o_y, 35, -45);

// For lower ray (I_e)
ctx.fillStyle = 'black';
for (let i = 0; i < 3; i++) {
    const dot_x = prism_center_x + 80 + i * 35;
    const dot_y = prism_center_y + (dot_x - prism_center_x) * angle_factor;
    ctx.beginPath();
    ctx.arc(dot_x, dot_y, 3, 0, 2 * Math.PI);
    ctx.fill();
}


// 7. Labels for outgoing rays
ctx.lineWidth = 2;
ctx.font = 'italic 22px Times New Roman';
ctx.fillStyle = 'black';
// I_o(t)
const io_x = ray_end_x + 10;
const io_y = o_ray_end_y;
ctx.fillText('I', io_x, io_y);
ctx.font = 'italic 16px Times New Roman';
ctx.fillText('o', io_x + 11, io_y + 5);
ctx.font = 'italic 22px Times New Roman';
ctx.fillText('(t)', io_x + 20, io_y);

// I_e(t)
const ie_x = ray_end_x + 10;
const ie_y = e_ray_end_y + 20;
ctx.fillText('I', ie_x, ie_y);
ctx.font = 'italic 16px Times New Roman';
ctx.fillText('e', ie_x + 11, ie_y + 5);
ctx.font = 'italic 22px Times New Roman';
ctx.fillText('(t)', ie_x + 20, ie_y);

</script>
</body>
</html>